#!/usr/bin/env python
#-*- coding:utf-8 -*-
#Filename: bbs_tool.py
#Author: meixiaor@gmail.com
import time
import os
import sys
import re
import string
import httplib
import urllib, urllib2

from BeautifulSoup import BeautifulSoup
from PyQt4 import QtCore,  QtGui

from Ui_bbs_login_multi import Ui_main_widget
import bbs_login

dic_user={}
#id->title
dic_title={}
#list_ID is the key of the above two dic, so smake sure it is distinct
#userid
list_ID=[]
#id->pic_url
dic_url={}

class person:
    def __init__(self, userid, passwd, total, step):
        self.userid=userid
        self.passwd=passwd
        self.total=total
        self.step=step
    def update(self, userid, passwd, total, step):
        self.userid=userid
        self.passwd=passwd
        self.total=total
        self.step=step
    def getUserInfo(self):
        return (self.userid, self.passwd, self.total, self.step)
#define the user's info
a_person=person("", "", "", "")
    
class BBS_QT(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setFixedSize(450,366)
        self.ui=Ui_main_widget()
        self.ui.setupUi(self)
            
        self.ui.passwd.setEchoMode(2)
        self.ui.passwd_2.setEchoMode(2)
                  
        self.ui.board.addItems(self.get_board())
        self.ui.board_2.addItems(self.get_board())
        QtCore.QObject.connect(self.ui.button_ok, QtCore.SIGNAL("clicked()"),self.fe_get_input)
        QtCore.QObject.connect(self.ui.button_stop, QtCore.SIGNAL("clicked()"),self.login_stop)
        
        QtCore.QObject.connect(self.ui.sure_cancel, QtCore.SIGNAL("accepted()"),self.post_get_input)
        QtCore.QObject.connect(self.ui.sure_cancel, QtCore.SIGNAL("rejected()"),self.post_cancel)
        
        QtCore.QObject.connect(self.ui.sure_cancel_2, QtCore.SIGNAL("accepted()"),self.start_crawl)
        QtCore.QObject.connect(self.ui.sure_cancel_2, QtCore.SIGNAL("rejected()"),self.start_crawl_stop)
        
        QtCore.QObject.connect(self.ui.link_whubbs, QtCore.SIGNAL("clicked()"),self.open_url)

    def open_url(self):
        os.system('"C:/Program Files/Internet Explorer/iexplore.exe" http://bbs.whu.edu.cn')
        
    def get_board(self):
        boards=[]
        f=file("board.txt", 'r')
        while True:
            line=f.readline()
            line="".join(line.split())
            if len(line)==0:
                break
            else:
                boards.append(line)
        return boards
        
    def fe_get_input(self):
        userid=self.ui.userid.text()
        #print userid
        passwd=self.ui.passwd.text()
        total=self.ui.total_number.value()
        step=self.ui.step_number.value()
        a_person.update(userid, passwd, total, step)
        #print userid, passwd, total, step
        if(a_person.userid==''):
            self.hint("please input userid!", "HINT")
        elif(a_person.passwd==''):
            self.hint("please input password!", "HINT")
        else:
            self.display("welcome %s, you want to login %s times with interval %s."%(a_person.userid, a_person.total, a_person.step))
            self.flag=1
            self.login_fe(a_person)
            
    def login_fe(self, a_person):
        i=0
        #print i
        while(i<a_person.total):
            if self.flag==0:
                break
            bbs_login.login(a_person.userid, a_person.passwd)
            self.display("successfully login %s times."%(i+1))
            time.sleep(a_person.step)
            #print i
            i=i+1
        if i==a_person.total:
            self.display("all http connection completed!")
            
    def login_stop(self):
        self.flag=0
        self.hint("the login process stoped!","HINT")
        self.ui.total_number.setValue(0)
        self.ui.step_number.setValue(0)
        self.ui.display_area.clear()    
    
    def post_get_input(self):
        userid=self.ui.userid_2.text()
        passwd=self.ui.passwd_2.text()
        board=self.ui.board.currentText()
        title=self.ui.title.text()
        content=self.ui.content.toPlainText()
        #print title
        #print content
        if(userid==''):
            self.hint("please input userid!","HINT")
        elif(passwd==''):
            self.hint("please input password!","HINT")
        else:
            cookies=bbs_login.login(userid, passwd)
        if(board==''):
            self.hint("please choose a board!","HINT")
        elif(title==''):
            self.hint("please input title!","HINT")
        elif(content==''):
            self.hint("please input content!","HINT")
        else:
            if((bbs_login.post(cookies, title, content, board))==200):
            #if True:
                self.hint("post successfully!", "HINT")
                self.ui.title.clear()
                self.ui.content.clear()
            else:
                self.hint("post failure!","HINT")

    def post_cancel(self):
        self.hint("Reset your subject and content!", "HINT")
        self.ui.title.clear()
        self.ui.content.clear()

    def start_crawl(self):
        board=self.ui.board_2.currentText()
        date_from=self.ui.dateFrom.date()
        date_to=self.ui.dateTo.date()
        userid=self.ui.search_ID.text()
        
        cookies=bbs_login.login("guest", '')
        if board=='':
            self.hint("please choose a board!","HINT") 
        elif self.is_less(date_to, date_from):
            self.hint("the start date must be less than the end date!", "HINT")
        else:
            self.get_page(cookies, board, date_from, date_to, userid)
            self.get_content(cookies, board)
            self.fetch_pic(board)
            print "download pic completely!"
        
    def start_crawl_stop(self):
        self.ui.progressBar.setValue(0)
        self.ui.search_ID.clear()

    def mk_dir(self, parent_dir, bname):
        flag=0
        for dname in os.listdir(parent_dir):
            if bname==dname:
                flag=1
                break
        if flag==0:
            os.mkdir(parent_dir+os.sep+bname)
    
    def fetch_pic(self, bname):
        global dic_url, dic_user, dic_title
        #print dic_title
        #initialization the progress bar
        self.ui.progressBar.setMinimum(0)
        self.ui.progressBar.setMaximum(len(dic_url))
        
        self.mk_dir(".", bname)
        # the number of pictures which has been sdownloaded
        pic_n=0
        for (id, pic_url_list) in dic_url.items():
            path="."+os.sep+bname
    #        mk_dir("."+os.sep+bname, dic_user[id])
            i=1
            for pic_url in pic_url_list:
                pic_name="%s-%s-%s_%s.jpg"%(dic_user[id], dic_title[id],  pic_n,  i)
                #print pic_name
    #            pic_path=path+os.sep+dic_user[id]+os.sep+pic_name
                pic_path=str(path)+os.sep+pic_name
                #print pic_path
                try:
                    urllib.urlretrieve(pic_url, pic_path)
                except IOError, e:
                    pic_name = "%s-%s.jpg"%(dic_user[id], pic_n)
                    pic_path=str(path)+os.sep+pic_name
                    urllib.urlretrieve(pic_url, pic_path)
                i=i+1
                pic_n=pic_n+1
                print "%s downloaded successfully! total:%s!"%(pic_n, pic_name)
            temp=self.ui.progressBar.value()+1
            self.ui.progressBar.setValue(temp) 
            
    def get_content(self, cookies, bname):
        #list_ID=[273481]
        global list_ID, dic_url
        url=bbs_login.url
        path='/wForum/disparticle.php'
        
        ck=cookies.split(",")
        header="WWWPARAMS=0;UTMPKEY=%s;UTMPNUM=%s;UTMPUSERID=%s"%(ck[0],ck[1],ck[2])
        h=httplib.HTTPConnection(url)
        
        ff = file('%s.txt'%bname, 'w+')
        for id in list_ID:
            temp_url_list=[]
            headers = {"Content-type":"application/x-www-form-urlencoded","Content-length":0}
            headers['Cookie']=header
            path_temp=path+"?boardName=%s&ID=%s"%(bname,id)
            h.request('GET',path_temp,"",headers)
            html=h.getresponse().read()
            #print html
            #bbs_login.file_write("test.html", html)
            for mm in re.finditer(r'<a href="bbscon.php\?bid=(\d+)&amp;id=(\d+)&amp;ap=(\d+)" target="_blank">', html):
                #print mm.groups()
                pic_temp_url="http://bbs.whu.edu.cn/wForum/bbscon.php?bid=%s&id=%s&ap=%s"%(mm.groups())
                temp_url_list.append(pic_temp_url)
                #dic_url[id]=pic_temp_url
                print pic_temp_url
            #crawl the text from the html
            self.get_text(ff, bname, html)
            dic_url[id]=temp_url_list
        ff.close()
        
    def get_text(self, ff, bname, html):
        soup = BeautifulSoup(html)
        td = soup('td', style="font-size:9pt;line-height:12pt;padding: 0px 5px;")
        if len(td)==0:
            return
        for item in td[0].contents:
            str_item = str(item)
            if re.match('^<', str_item) == None:
                str_item = re.sub('(&nbsp;)',' ',  str_item)
                ff.write(str_item)
                ff.write('\n')
            elif re.match('^<a', str_item) != None:
                try:
                    ff.write(item.string)
                except TypeError, e:
                    ff.write(' ')
                ff.write('\n')
            else:
                pass
        ff.write('\n\n')
#        content = soup.findAll('td', style="font-size:9pt;line-height:12pt;padding: 0px 5px;")
#        for item in content:
#            ss = re.sub('</?\w+[^>]*>', '', str(item.string))
#            ss = re.sub('<br\s*?/?>', '\n', ss)
#            ss = re.sub('&nbsp', ' ', ss)
#            ff.write(ss)
#            ff.write("\n\n")
        
        
    def get_page(self, cookies, bname, date_from, date_to, s_userid=None):
        global list_ID, dic_title, dic_user
        exclude=[]
        url=bbs_login.url
        path='/wForum/board.php'
    
        ck=cookies.split(",")
        header="WWWPARAMS=0;UTMPKEY=%s;UTMPNUM=%s;UTMPUSERID=%s"%(ck[0],ck[1],ck[2])
        h=httplib.HTTPConnection(url)
        bpage=1
        flag=0
        while flag==0 and bpage<20:
            exclude=[1]*30
            temp_list_ID=[]
            headers = {"Content-type":"application/x-www-form-urlencoded","Content-length":0}
            headers['Cookie']=header
            path_temp=path+"?name=%s&page=%s"%(bname,bpage)
            h.request('GET',path_temp,"",headers)
            html=h.getresponse().read()
            #bbs_login.file_write("test.html", html)
            #print html
            #get the ID and the userid of the articles
            flag_a=0
            for mm in re.finditer(r'''origin = new Post\((\d*), '(\w*)', '(.*)', '(.*)'\);''', html):
                print mm.groups()
                    #print "it's d here!"
                t=mm.group(3)
                id=mm.group(1)
                userid=mm.group(2)
                year=t.partition("-")[0]
                month=t.partition("-")[2].partition("-")[0]
                day=t.partition("-%s-"%(month))[2].partition(" ")[0]
                current_date=QtCore.QDate(int(year), int(month), int(day))
                #print current_date
                if self.is_less(date_from, current_date) and self.is_less(current_date, date_to):
                    #print "hello"
                    id=mm.group(1)
                    #print userid
                    #print id
                    if s_userid==None or s_userid=='' or userid==s_userid:
                        exclude[flag_a]=0
                else:
                    pass
#                    print "time not included!"
                if exclude[flag_a]==0:
                    list_ID.append(id)
                    temp_list_ID.append(id)
                    dic_user[id]=mm.group(2)
                flag_a=flag_a+1
            #print list_ID
            #get the title of the article
            print exclude
            flag_b=0
            #print html
            flag_c=0
            for nn in re.finditer(r'''writepost\((\d*), '(.*)', (\d*), origin, lastreply, (.*), (.*)\);''', html):
                #print nn.groups()
                if exclude[flag_b]==0:
                    dic_title[temp_list_ID[flag_c]]=nn.group(2)
                    flag_c=flag_c+1
                flag_b=flag_b+1
            bpage=bpage+1
            #print bpage
        #print flag
    
    def is_less(self, a, b):
        (a_year, a_month, a_day)=(a.year(), a.month(), a.day())
        (b_year, b_month, b_day)=(b.year(), b.month(), b.day())
        if a_year<b_year:
            return True
        elif a_year==b_year:
            if a_month<b_month:
                return True
            elif a_month==b_month:
                if a_day<=b_day:
                    return True
                else:
                    return False
            else:
                return False
        else:
            return False
        
    #not used here
    def get_time(self, years, months, days):
        now=time.localtime()
    #    delta_day=now.tm_mday-days
        if now.tm_mday-days<0:
            t_day=0
            months=months+1
        else:
            t_day=now.tm_mday-days
        if now.tm_mon-months<0:
                t_mon=0
                years=years+1
        else:
            t_mon=now.tm_mon-months
        t_year=now.tm_year-years
        
        print (t_year, t_mon, t_day)
        return (t_year, t_mon, t_day)


    def hint(self, content, title):
        message=QtGui.QMessageBox(self)
        message.setText(content)
        message.setWindowTitle(title)
        message.exec_()
    
    def display(self, content):
        self.ui.display_area.append(content)        
        
def main_test():
    httplib.HTTPConnection.debuglevel=1
    
    if len(sys.argv)!=3:
        print "Usage: %s UserName Password"%sys.argv[0]
        sys.exit(0)
    userid=sys.argv[1]
    passwd=sys.argv[2]
    total=5
    step=6
    login_fe(total, step, userid, passwd)

if __name__=='__main__':
    httplib.HTTPConnection.debuglevel=1
    reload(sys)
    sys.setdefaultencoding('utf-8')
    app=QtGui.QApplication(sys.argv)
    myapp=BBS_QT()
    myapp.show()
    sys.exit(app.exec_())
